<template>
	<view class="poster">
		<moPosterTools :zoomIn="area.scale" :rotateIn="area.rotate" @active="onActive"></moPosterTools>
		<view class="poster-img" @touchstart="touchstartCallback"
			@touchmove="touchmoveCallback" @touchend="touchendCallback">
			<image :src="posterPicUrl" :style="{
				transform: `translate(${area.offsetX}px,${area.offsetY}px) scale(${area.scale}) rotate(${ area.rotate }deg)`,
				width:`${originImg.width}px`,
				height:`${originImg.height}px`
			}"></image>
		</view>
	</view>
</template>

<script>
	import moPosterTools from './mo-poster-tools.vue';
	var twoPoint = {
		x1: 0,
		y1: 0,
		x2: 0,
		y2: 0
	}
	function requestTimeout(timeout) {
		return function(callback) {
			setTimeout(callback, timeout);
		};
	}
	const createRequestAnimationFrame = (refreshRate) => {
		var timeout = null;

		// Convert refreshRate to timeout
		if (refreshRate !== "auto" && refreshRate < 60 && refreshRate > 1) {
			timeout = Math.floor(1000 / refreshRate);
		}

		if (timeout === null) {
			return requestAnimationFrame || requestTimeout(33);
		} else {
			return requestTimeout(timeout);
		}
	}
	export default {
		name: 'mo-poster',
		components: {
			moPosterTools
		},
		props: {
			posterPicUrl: {
				type: String,
				default () {
					return '';
				}
			},
			width:{
				type: Number,
				default:320
			},
			height:{
				type: Number,
				default:400
			}
		},
		data() {
			return {
				picUrlInfo: {},
				addHeight: false,
				ipad: false,
				originImg: {}, //存放原图信息
				area: {
					offsetX: 0, //剪裁图片左上角坐标x
					offsetY: 0, //剪裁图片左上角坐标y
					zoom: false, //是否缩放状态
					distance: 0, //两指距离
					scale: 2, //缩放倍数
					rotate: 0, //旋转角度
					ax: 0, // 松开手指后偏移量
					ay: 0, // 松开手指后偏移量
					speedX: 0,
					speedY: 0,
					angle: 0,
				},
				arrts: [],
				bgImageInfo: {},
				bgscle: 0,
				startX: 0,
				startY: 0,
			};
		},
		watch: {
			posterPicUrl: {
				deep: true,
				immediate: true,
				handler(newVal) {
					console.log(newVal, 'newVal')
					this.$nextTick(() => {
						// this.initImg(newVal)
					})
				}
			}
		},
		methods: {
			onActive(item) {
				console.log(778, item)
				this.area.scale = item.zoom
				this.area.rotate = item.rotate
				if (item.name === '定位') {
					this.area.scale = 1
					this.area.rotate = 0
					this.area.offsetX = 0
					this.area.offsetY = 0
				}
			},
			rotate() {
				let _this = this;
				_this.area.rotate % 90 == 0 ? _this.area.rotate = _this.area.rotate + 90 : _this.area.rotate = 0

			},
			getImageInfo(image) {
				return new Promise((req, rej) => {
					uni.getImageInfo({
						src: image,
						success: function(res) {
							req(res)
						},
					});
				})
			},
			// async getPosters(bgImageURL) {
			// 	let bgImageInfo = await this.getImageInfo(bgImageURL)
			// 	this.aspectRatio = Number((bgImageInfo.height/bgImageInfo.width).toFixed(2))
			// 	console.log(Number((bgImageInfo.height/bgImageInfo.width).toFixed(2)),'bgImageInfo--',this.width,this.height)
				
			// },
			initImg(url) {
				let _this = this;
				uni.getImageInfo({
					src: url,
					success(resopne) {
						let innerAspectRadio = Number((resopne.height / resopne.width).toFixed(2)) 
						console.log(99, innerAspectRadio, resopne)
						if (_this.width < resopne.width) {
							_this.originImg.src = url
							_this.originImg.width = Number(_this.width)
							_this.originImg.height = Number(_this.width*innerAspectRadio)
							_this.area.offsetX = 0
							_this.area.offsetY = 0
							_this.area.zoom = false
							_this.area.distance = 0
							_this.area.scale = 1
							_this.area.rotate = 0
						} else {
							_this.originImg.src = url
							_this.originImg.width = Number(resopne.width)
							_this.originImg.height = Number(resopne.height)
							_this.area.offsetX = 0
							_this.area.offsetY = 0
							_this.area.zoom = false
							_this.area.distance = 0
							_this.area.scale = 1
							_this.area.rotate = 0
						}
						
						console.log(resopne,'initImg---',innerAspectRadio,_this.originImg)
						
					},
					fail(err) {
						console.log(126, err)

					}
				})
			},
			//事件处理函数
			touchstartCallback: function(e) {
				if (e.touches.length === 1) {
					let {
						clientX,
						clientY
					} = e.touches[0];
					this.startX = clientX;
					this.startY = clientY;
					this.touchStartEvent = e.touches;
				} else {
					let xMove = e.touches[1].clientX - e.touches[0].clientX;
					let yMove = e.touches[1].clientY - e.touches[0].clientY;
					let distance = Math.sqrt(xMove * xMove + yMove * yMove);
					twoPoint.x1 = e.touches[0].pageX * 2
					twoPoint.y1 = e.touches[0].pageY * 2
					twoPoint.x2 = e.touches[1].pageX * 2
					twoPoint.y2 = e.touches[1].pageY * 2
					this.area.distance = distance
					this.area.zoom = true
					// _this.area.rotate = 0
				}
			},
			//图片手势动态缩放
			touchmoveCallback: function(e) {
				let _this = this
				if (e.touches.length === 1) {
					//单指移动
					if (_this.area.zoom) {
						//缩放状态，不处理单指
						return;
					}
					let {
						clientX,
						clientY
					} = e.touches[0];
					let offsetX = clientX - _this.startX;
					let offsetY = clientY - _this.startY;
					_this.startX = clientX;
					_this.startY = clientY;
					let { area } = _this;
					area.offsetX += offsetX;
					area.offsetY += offsetY;
					area.offsetX = Math.floor(area.offsetX);
					area.offsetY = Math.floor(area.offsetY);
					_this.area = area
					_this.arrts.unshift({
						clientX, clientY,
						timeStamp: e.timeStamp
					})
					if (_this.arrts.length > 30) {
						_this.arrts.splice(30)
					}

				} else if (e.touches.length === 2) {
					//计算旋转
					let preTwoPoint = JSON.parse(JSON.stringify(twoPoint))
					twoPoint.x1 = e.touches[0].pageX * 2
					twoPoint.y1 = e.touches[0].pageY * 2
					twoPoint.x2 = e.touches[1].pageX * 2
					twoPoint.y2 = e.touches[1].pageY * 2

					function vector(x1, y1, x2, y2) {
						this.x = x2 - x1;
						this.y = y2 - y1;
					};

					//计算点乘
					function calculateVM(vector1, vector2) {
						return (vector1.x * vector2.x + vector1.y * vector2.y) / (Math.sqrt(vector1.x * vector1.x +
							vector1.y * vector1.y) * Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y));

					}
					//计算叉乘
					function calculateVC(vector1, vector2) {
						return (vector1.x * vector2.y - vector2.x * vector1.y) > 0 ? 1 : -1;
					}

					let vector1 = new vector(preTwoPoint.x1, preTwoPoint.y1, preTwoPoint.x2, preTwoPoint.y2);
					let vector2 = new vector(twoPoint.x1, twoPoint.y1, twoPoint.x2, twoPoint.y2);
					let cos = calculateVM(vector1, vector2);
					let angle = Math.acos(cos) * 180 / Math.PI;

					let direction = calculateVC(vector1, vector2);
					let _allDeg = direction * angle;


					// 双指缩放
					// let xMove = e.touches[1].clientX - e.touches[0].clientX;
					// let yMove = e.touches[1].clientY - e.touches[0].clientY;
					// let distance = Math.ceil(Math.sqrt(xMove * xMove + yMove * yMove));
					// let distanceDiff = distance - _this.area.distance;
					// let newScale = _this.area.scale + 0.005 * distanceDiff;

					if (Math.abs(_allDeg) > 1) {
						// _this.area.rotate = _this.area.rotate + _allDeg
					} else {
						//双指缩放
						let xMove = e.touches[1].clientX - e.touches[0].clientX;
						let yMove = e.touches[1].clientY - e.touches[0].clientY;
						// let distance = Math.sqrt(xMove * xMove + yMove * yMove);
						let distance = Math.ceil(Math.sqrt(xMove * xMove + yMove * yMove));
						let distanceDiff = distance - _this.area.distance;
						let newScale = _this.area.scale + 0.005 * distanceDiff;
						if (newScale < 0.2 || newScale >= 4.2) {
							return;
						}
						_this.area.distance = distance
						_this.area.scale = newScale
						// _this.area.rotate = 0
					}
				} else {
					return;
				}
			},
			touchendCallback: function(e) {
				//触摸结束
				if (e.touches.length === 0) {
					this.area.zoom = false
				}
				// 惯性运动
				if (this.arrts.length >= 3) {
					function vector(x1, y1, x2, y2, t1, t2) {
						this.x = x2 - x1 > 10 ? 10 : Math.max(x2 - x1, -10);
						this.y = y2 - y1 > 10 ? 10 : Math.max(y2 - y1, -10);
						this.t = t2 - t1;
					};
					const s2 = this.arrts[0]
					const s1 = this.arrts[1]
					const vector1 = new vector(s1.clientX, s1.clientY, s2.clientX, s2.clientY, s1.timeStamp, s2.timeStamp);


					this.area.vx = vector1.x / vector1.t
					this.area.vy = vector1.y / vector1.t
					this.area.dirX = (vector1.x >> 31) * 2 + 1  // x运动方向 位运算>>31 正数为0 负数为-1 ，即 正：1   负：-1
					this.area.dirY = (vector1.y >> 31) * 2 + 1  // y运动方向
					const angle = vector1.y == 0 ? 90 : 180 * Math.atan(Math.abs(vector1.x/vector1.y)) / Math.PI // x与运动方向夹角
					
					// 根据角度分解加速度, 0.003-0.006是比较合适的加速度值
					const a = 0.003
					this.area.ax = this.area.dirX * a * Math.sin(angle * Math.PI/180);
					this.area.ay = this.area.dirY * a * Math.cos(angle * Math.PI/180);

					this.animate()
				}
			},
			animate() {
				const t = 30 // 按一帧30sm计算

				let vxt = this.area.vx - this.area.ax * t; // 计算x当前速度
				vxt = this.area.dirX > 0 ? Math.max(vxt, 0) : Math.min(vxt, 0);
				
				let vyt = this.area.vy - this.area.ay * t; // 计算y当前速度
				vyt = this.area.dirY > 0 ? Math.max(vyt, 0) : Math.min(vyt, 0);
				
				if( vxt == 0 && vyt == 0) {
					this.arrts = []
					//停止运动 
					return
				}
				//更新UI 
				const dx = t * (vxt + this.area.vx) / 2; //计算x当前位移 
				const dy = t * (vyt + this.area.vy) / 2; //计算y当前位移 
				this.area.offsetX += dx; //移动 
				this.area.offsetY += dy;
				this.area.vx = vxt // 速度衰减
				this.area.vy = vyt

				//继续下一帧运动 
				let requestAFrame = createRequestAnimationFrame(t);
				requestAFrame(this.animate)
			},
		}
	}
</script>

<style lang="scss" scoped>
	.poster {
		width: 100vw;
		height: 100%;
		overflow-x:auto;
		overflow-y:hidden;
		display: flex;
		align-items: center;
		justify-content: center;
		flex-direction: column;

		.poster-img {
			width: 100%;
			height: 100%;
			overflow: hidden;
			background: #fff;
			// border-radius: 32rpx;
			margin: 0 auto;
			background-image: linear-gradient(90deg, rgba(235, 235, 235, 0.38) 10%, rgba(0, 0, 0, 0) 10%), linear-gradient(rgba(235, 235, 235, 0.38) 10%, rgba(0, 0, 0, 0) 10%);
			background-size: 17px 17px;
		}
	}
</style>
